package edu.gtcfla.km.repositories.page;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vsg.common.page.PaginationKeyword;
import org.vsg.common.page.datatrans.DataTransformer;
import org.vsg.common.page.hiberante4.HibernatePageProcessor;
import org.vsg.common.page.processor.PaginationProcessorException;

import edu.gtcfla.km.model.KnowledgeD;



/**
 * @author Bill Vison
 *
 */
public class KnowledgeCurrentUserPermProc extends HibernatePageProcessor {



	private static final Logger logger = LoggerFactory.getLogger(KnowledgeCurrentUserPermProc.class);	
	
	
	private Set<String> cateIds;
	
	private String currentUserId;
	
	private String userGroupId;
	

	public Set<String> getCateIds() {
		return cateIds;
	}


	public void setCateIds(Set<String> cateIds) {
		this.cateIds = cateIds;
	}


	public String getCurrentUserId() {
		return currentUserId;
	}


	public void setCurrentUserId(String currentUserId) {
		this.currentUserId = currentUserId;
	}


	public String getUserGroupId() {
		return userGroupId;
	}


	public void setUserGroupId(String userGroupId) {
		this.userGroupId = userGroupId;
	}


	/* (non-Javadoc)
	 * @see org.vsg.commons.util.pagination.processor.PaginationProcessor#getPaginationList(org.vsg.commons.util.pagination.datatrans.DataTransformer)
	 */
	public List getPageList(DataTransformer transformer)
			throws PaginationProcessorException {
		// TODO Auto-generated method stub
		List dataList = new Vector();


		int offset = (Integer)transformer.getImplicitValue(PaginationKeyword.TFS_DATA_OFFSET);
		int rows = (Integer)transformer.getImplicitValue(PaginationKeyword.TFS_ROWS);
		
	
		StringBuffer query = new StringBuffer("select ");
		query.append("knowledge.id , knowledge.title , knowledge.shared , knowledge.releasedUserId , knowledge.releasedDate, ");
		query.append("knowledge.content , knowledge.keywords ");
		query.append("from ").append(KnowledgeD.class.getName() );
		query.append(" as knowledge ");
		query.append("left join knowledge.categoryD as cate ");
		
		
		// -------------- get the condition for the query 
		query.append("where ");
		query.append("cate.id in (:cateIds) ");
		query.append(" and ( ");
		query.append(" (knowledge.shared = 0 and knowledge.releasedUserId = :userId) ");
		if (userGroupId != null) {
			query.append(" OR (knowledge.shared = 1 and knowledge.userGroupId = :userGroupId) ");
		}
		query.append(" OR knowledge.shared = 2 ");
		query.append(") ") ;
		
		String queryString = (String)transformer.getValue("query");

		if (queryString != null && !queryString.equals("")) {
			query.append("and knowledge.title like :query ");
		}
		
		if (logger.isInfoEnabled()) {
			logger.info("Execute SQL :"+query.toString());
		}
		

		
		Session sess = this.getSession();
		
		try {
			Query hql = sess.createQuery( query.toString() );
			hql.setParameterList("cateIds", this.cateIds);
			
			hql.setParameter("userId", this.currentUserId );
			if (userGroupId != null) {
				hql.setParameter("userGroupId", this.userGroupId );
			}
			if (queryString != null && !queryString.equals("")) {
				hql.setParameter("query", "%" + queryString + "%");
			}
			
			
			hql.setFirstResult(offset);
			hql.setMaxResults(rows);			
			
			Iterator dataIter = (Iterator)hql.iterate();
			
			Object[] fields = null;
			while (dataIter.hasNext()) {
				fields = (Object[])dataIter.next();
				
				int i = 0;
				KnowledgeD kld = new KnowledgeD();
				kld.setId( (String)fields[i++] );
				kld.setTitle( (String)fields[i++] );
				kld.setShared( (Short)fields[i++] );
				kld.setReleasedUserId( (String)fields[i++] );
				kld.setReleasedDate( (Date)fields[i++] );
				
				kld.setContent( (String)fields[i++]  );
				kld.setKeywords( (String)fields[i++]  );
				
				dataList.add( kld );				
			}
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return dataList;
	}


	/* (non-Javadoc)
	 * @see org.vsg.commons.util.pagination.processor.PaginationProcessor#getTotalRecords(org.vsg.commons.util.pagination.datatrans.DataTransformer)
	 */
	public int getTotalRecords(DataTransformer transformer)
			throws PaginationProcessorException {
		// TODO Auto-generated method stub
		int totalRecord = 0;
		
		StringBuffer query = new StringBuffer("SELECT ");
		query.append("count(*) ");
		query.append("FROM ").append(KnowledgeD.class.getName());
		query.append(" as knowledge ");
		query.append("left join knowledge.categoryD as cate ");		
	
		// -------------- get the condition for the query 
		query.append("where ");
		query.append("cate.id in (:cateIds) ");

		query.append(" and ( ");
		query.append(" (knowledge.shared = 0 and knowledge.releasedUserId = :userId) ");
		if (userGroupId != null) {
			query.append(" OR (knowledge.shared = 1 and knowledge.userGroupId = :userGroupId) ");
		}
		query.append(" OR knowledge.shared = 2 ");
		query.append(") ") ;
		
		String queryString = (String)transformer.getValue("query");
		if (queryString != null && !queryString.equals("")) {
			query.append("and knowledge.title like :query ");
		}		
		
		if (logger.isInfoEnabled()) {
			logger.info("Execute SQL :"+query.toString());
		}
		
		
		Session sess = this.getSession();
		Query hql = sess.createQuery( query.toString() );
		hql.setParameterList("cateIds", this.cateIds);
		
		hql.setParameter("userId", this.currentUserId );
		if (userGroupId != null) {
			hql.setParameter("userGroupId", this.userGroupId );
		}
		if (queryString != null && !queryString.equals("")) {
			hql.setParameter("query", "%" + queryString + "%");
		}
		
		Iterator iter = hql.iterate();			
		while (iter.hasNext()) {
			totalRecord = new Integer(iter.next().toString());
		}
		
		return totalRecord;
	}
	
	


}